home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
source
/
vr386
/
refresh.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-10
|
10KB
|
330 lines
/* COMPLETELY rewritten by Dave Stampe Dec. 1993, */
/* used to be render.c, now split off to uservid.c and this file */
// This code is the refresh-screen call. All the other stuff was
// moved to uservid.c
// Also has Dave's axis-compass (much improved) and the new
// prerender/postrender support
/*
This code is part of the VR-386 project, created by Dave Stampe.
VR-386 is a desendent of REND386, created by Dave Stampe and
Bernie Roehl. Almost all the code has been rewritten by Dave
Stampre for VR-386.
Copyright (c) 1994 by Dave Stampe:
May be freely used to write software for release into the public domain
or for educational use; all commercial endeavours MUST contact Dave Stampe
(dstampe@psych.toronto.edu) for permission to incorporate any part of
this software or source code into their products! Usually there is no
charge for under 50-100 items for low-cost or shareware products, and terms
are reasonable. Any royalties are used for development, so equipment is
often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to VR-386 and Dave Stampe,
and any other authors in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling!
DEVELOPMENT: VR-386 is a effort to develop the process started by
REND386, improving programmer access by rewriting the code and supplying
a standard API. If you write improvements, add new functions rather
than rewriting current functions. This will make it possible to
include you improved code in the next API release. YOU can help advance
VR-386. Comments on the API are welcome.
CONTACT: dstampe@psych.toronto.edu
*/
#include <stdio.h>
#include <dos.h>
#include <stdlib.h> /* labs */
#include "f3dkitd.h"
#include "vr_api.h"
#include "pcdevice.h" // register_render_start,end
#include "intmath.h"
#include "splits.h"
#define MAIN_VGA 1 /* for multi-VGA only */
#define LEFT_VGA 2
#define RIGHT_VGA 4
#define ALL_VGA 7
#define MONOSCOPIC 0 /* stereo types */
#define SWITCHED 1
#define SPLITLR 3
#define SEPARATE 5
extern struct Screeninfo *screeninfo;
extern int swap_eyes;
extern int show_location, show_compass, show_framerate; // options
extern int use_glove;
extern void user_draw_line(int x1, int y1, int x2, int y2, int color);
// draw an axis compass
// placed at abs. screen position and size
// has visibility sort, but no perspective
// usually just draw one eye for stereo,
// since results are disappointing without perspective
static do_axis(int xc, int yc, int x, int y, int bcolor, int xcolor, char c)
{
char st[] = "x";
st[0] = c;
if (current_orientation & XFLIP)
{
user_draw_line(xc,yc,xc-x,yc-y,bcolor);
user_text(xc-x-5,yc-y,bcolor,st);
user_draw_line(xc-1,yc+1,xc-1-x,yc+1-y,xcolor);
user_text(xc-x-5-1,yc-y+1,xcolor,st);
}
else
{
user_draw_line(xc,yc,x+xc,yc-y,bcolor);
user_text(x+xc+5,yc-y,bcolor,st);
user_draw_line(xc+1,yc+1,x+xc+1,yc-y+1,xcolor);
user_text(x+xc+5+1,yc-y+1,xcolor,st);
}
}
// xc,yx : screen location of center
// V : viewport
// xcolor,ycolor,zcolor: color of axes
// bcolor: "shadow" color
void coord_ref(WORD xc, WORD yc, WORD size, VIEW *v,
WORD xcolor, WORD ycolor, WORD zcolor, WORD bcolor)
{
MATRIX m;
int i;
long x[3], y[3], z[3]; // coords from axes
int order[3] = {0,1,2}; // sort terms
int color[3];
char label[3] = {'x','y','z'}; // labels
if (show_compass == 0) return;
color [0] = xcolor;
color [1] = ycolor;
color [2] = zcolor;
view_to_matrix(v,m); // transform for axes
m[3][0] = m[3][1] = m[3][2] = 0;
matrix_transpose(m,m);
x[0] = size; y[0] = 0; z[0] = 0; // axes to screen locations
x[1] = 0; y[1] = size; z[1] = 0;
x[2] = 0; y[2] = 0; z[2] = size;
matrix_point(m, &x[0], &y[0], &z[0]);
matrix_point(m, &x[1], &y[1], &z[1]);
matrix_point(m, &x[2], &y[2], &z[2]);
// aspect ratio fixup
y[0] = mulmuldiv(y[0],screeninfo->aspect,65536L);
y[1] = mulmuldiv(y[1],screeninfo->aspect,65536L);
y[2] = mulmuldiv(y[2],screeninfo->aspect,65536L);
if (z[order[0]]<=z[order[1]]) // sort by depth so deepest first
{
i = order[0];
order[0] = order[1];
order[1] = i;
}
if (z[order[0]]<=z[order[2]])
{
i = order[0];
order[0] = order[2];
order[2] = i;
}
if (z[order[1]]<=z[order[2]])
{
i = order[1];
order[1] = order[2];
order[2] = i;
}
do_axis(xc,yc, x[order[0]], y[order[0]], bcolor, color[order[0]], label[order[0]]);
do_axis(xc,yc, x[order[1]], y[order[1]], bcolor, color[order[1]], label[order[1]]);
do_axis(xc,yc, x[order[2]], y[order[2]], bcolor, color[order[2]], label[order[2]]);
}
static VIEW left_view, right_view;
void stop_stereo()
{
right_page = left_page = current_video_page; /* stop stereo for now */
}
//////////////////////////////////////////
/// THESE ROUTINES LET YOU CONTROL HOW THE
/// SCREEN IS CLEARED AND WHAT IS DISPLAYED
/// THE ARGUMENTS ARE:
/// v : the view being draw. left/right eye views are different
/// vpage: the video page being drawn
/// isfirst, islast: 1 if this is the first/last access to the
/// video page. Useful for toggling screen
/// clears etc. when several views are on the
/// same page
/// whicheye: 0 for left eye/mono, 1 for right eye view
///
// found in <USCREEN.C>
// This is called before drawing objects. It should
// at least clear the screen
void prerender_process(VIEW *v, unsigned vpage, WORD isfirst, WORD whicheye);
// This is called after drawing objects. It can be used
// to put up status, etc.
// lots of if() stuff, but just because we're supporting
// so many stereo types
void postrender_process(VIEW *v, unsigned vpage, WORD islast, WORD whicheye);
// where to save the screen while using menus
WORD screen_save_video_page = 1;
static WORD last_visible_video_page = 0;
BOOL screen_has_been_saved = FALSE;
extern int reframe;
void screen_refresh(CAMERA *c) /* now does stereo drawing */
{
int mxpge = 2;
char st[100];
VIEW *v;
BOOL was_visible;
register_render_start();
screen_save_video_page = current_video_page;
last_visible_video_page = current_video_page;
if (screeninfo->pages < 3) mxpge = 1; else mxpge = 2;
if(mxpge<2) vsync();
if (stereo_type == MONOSCOPIC)
{
current_video_page++;
if (current_video_page > mxpge) current_video_page = 0;
was_visible = last_cursor_hide(current_video_page);
set_drawpage(current_video_page);
v = select_camera_view(c,0);
prerender_process(v, current_video_page, 1, 0);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 1, 0);
set_vpage(current_video_page);
}
else if (stereo_type==SPLITLR)
{
current_video_page++;
if (current_video_page > mxpge) current_video_page = 0;
was_visible = last_cursor_hide(current_video_page);
v = select_camera_view(c,LEFT_EYE);
set_drawpage(current_video_page);
prerender_process(v, current_video_page, 1, 0&LEFT_EYE);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 0, LEFT_EYE);
v = select_camera_view(c,RIGHT_EYE);
set_drawpage(current_video_page);
prerender_process(v, current_video_page, 0, RIGHT_EYE);
set_drawpage(current_video_page);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 1, RIGHT_EYE);
set_vpage(current_video_page);
}
else if (stereo_type == SWITCHED)
{
current_video_page = current_video_page ^ 2; // need 4 pages for this!
was_visible = last_cursor_hide(current_video_page);
v = select_camera_view(c,LEFT_EYE);
while ((has_switched&1) == 0) if (kbhit()) break; // wait if not seen yet
set_drawpage(current_video_page);
prerender_process(v, current_video_page, 1, LEFT_EYE);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 1, LEFT_EYE);
v = select_camera_view(c,RIGHT_EYE);
while ((has_switched&2) == 0) if (kbhit()) break;
set_drawpage(current_video_page+1);
prerender_process(v, current_video_page+1, 1, RIGHT_EYE);
render_split(global_world_root, v);
postrender_process(v, current_video_page+1, 1, RIGHT_EYE);
disable();
if (swap_eyes)
{
left_page = current_video_page+1; /* display them now */
right_page = current_video_page;
}
else
{
left_page = current_video_page;
right_page = current_video_page+1;
}
has_switched = 0;
enable();
}
else if (stereo_type == SEPARATE) // seperate VGA buffers
{
current_video_page++;
if (current_video_page > mxpge) current_video_page = 0;
was_visible = last_cursor_hide(current_video_page);
set_drawpage(current_video_page);
VGA_select(swap_eyes ? RIGHT_VGA : LEFT_VGA);
v = select_camera_view(c,LEFT_EYE);
prerender_process(v, current_video_page, 1, LEFT_EYE);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 1, LEFT_EYE);
VGA_select(swap_eyes ? LEFT_VGA : RIGHT_VGA);
v = select_camera_view(c,RIGHT_EYE);
prerender_process(v, current_video_page, 1, RIGHT_EYE);
render_split(global_world_root, v);
postrender_process(v, current_video_page, 1, RIGHT_EYE);
VGA_select(LEFT_VGA);
set_vpage(current_video_page);
VGA_select(RIGHT_VGA);
set_vpage(current_video_page);
VGA_select(MAIN_VGA); // usually same as left
}
register_render_end();
cursor_show(); // draw to current page
set_drawpage(current_video_page);
screen_has_been_saved = FALSE;
}